﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace OCRTheNewHope
{
    public static class FileOperations
    {
        public static Random rnd = new Random();

        public static Digit[] ReadDatabase(string path, long skip = 0, int total = -1)
        {
            Digit[] rVal;

            using (BinaryReader b = new BinaryReader(File.Open(path, FileMode.Open)))
            {
                int length = b.ReadInt32();
                int width = b.ReadInt32();
                int height = b.ReadInt32();

                length = total > 0 ? total : length;
                rVal = new Digit[length];

                b.BaseStream.Seek(skip * ( width * height * 9 + 5 ) , SeekOrigin.Current);

                for (int k = 0; k < rVal.Length; k++)
                {
                    int digitID = b.ReadInt32();
                    byte digitValue = b.ReadByte();

                    byte[,] original = new byte[height, width];
                    float[,] integral = new float[height, width];

                    for (int i = 0; i < height; i++)
                        for (int j = 0; j < width; j++)
                            original[i, j] = b.ReadByte();

                    for (int i = 0; i < height; i++)
                        for (int j = 0; j < width; j++)
                            integral[i, j] = (float)b.ReadDouble();

                    //rVal[k] = new Digit(digitID, digitValue, original, integral);
                    rVal[k] = new Digit(digitID, digitValue, null, integral);
                }
            }

            return rVal;
        }

        public static Digit[] ReadDatabaseRandomly(string path, int total = -1)
        {
            Digit[] rVal;

            using (BinaryReader b = new BinaryReader(File.Open(path, FileMode.Open)))
            {
                int totalLength = b.ReadInt32();
                int width = b.ReadInt32();
                int height = b.ReadInt32();

                int length = total > 0 ? total : totalLength;
                rVal = new Digit[length];

                for (int k = 0; k < rVal.Length; k++)
                {
                    long randomNumber = FileOperations.rnd.Next(totalLength);
                    b.BaseStream.Seek(12 + randomNumber * (width * height * 9 + 5), SeekOrigin.Begin);

                    int digitID = b.ReadInt32();
                    byte digitValue = b.ReadByte();

                    byte[,] original = new byte[height, width];
                    float[,] integral = new float[height, width];

                    for (int i = 0; i < height; i++)
                        for (int j = 0; j < width; j++)
                            original[i, j] = b.ReadByte();

                    for (int i = 0; i < height; i++)
                        for (int j = 0; j < width; j++)
                            integral[i, j] = (float)b.ReadDouble();

                    rVal[k] = new Digit(digitID, digitValue, original, integral);
                }
            }

            return rVal;
        }

        public static BinaryWriter CreateHeader(string path, int numItems, int numRows, int numCols)
        {
            BinaryWriter b = new BinaryWriter(File.Open(path, FileMode.Create));

            b.Write(numItems);
            b.Write(numRows);
            b.Write(numCols);

            return b;
        }

        public static void WriteDatabase(BinaryWriter b, Digit[] digits)
        {              
            for (int i = 0; i < digits.Length; i++)
            {
                b.Write(digits[i].DigitID);
                b.Write((byte)digits[i].DigitValue);

                for (int j = 0; j < digits[i].OriginalGrayscaleMatrix.GetLength(0); j++)
                    for (int k = 0; k < digits[i].OriginalGrayscaleMatrix.GetLength(1); k++)
                        b.Write((byte)digits[i].OriginalGrayscaleMatrix[j, k]);

                for (int j = 0; j < digits[i].IntegralMatrix.GetLength(0); j++)
                    for (int k = 0; k < digits[i].IntegralMatrix.GetLength(1); k++)
                        b.Write(digits[i].IntegralMatrix[j, k]);
            }
        }

        public static string GetPath()
        {
            int counter = -1;
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            string rVal = "";
            do
            {
                counter++;
                rVal = desktopPath + "\\logs" + counter.ToString("D3") + ".txt";
            }
            while (File.Exists(rVal));

            return rVal;
        }
    }
}
